#include "../HObject.h"
#include "../Log.h"
#include "Vector.h"

namespace helix
{

	Vector::Vector() : HObject()
	{
		vector[0]=0;
		vector[1]=0;
		vector[2]=0;
	}

	Vector::Vector(float x,float y,float z) : HObject()
	{
		vector[0]=x;
		vector[1]=y;
		vector[2]=z;
	}


	Vector Vector::operator + (Vector &v)
	{
		Vector temp;

		temp.vector[0]=vector[0]+v.vector[0];
		temp.vector[1]=vector[1]+v.vector[1];
		temp.vector[2]=vector[2]+v.vector[2];

		return temp;
	}

	Vector Vector::operator += (Vector &v)	     //overload the += operator to add vectors
	{
		vector[0]+=v.vector[0];
		vector[1]+=v.vector[1];
		vector[2]+=v.vector[2];

		return *this;                        //return this vector
	}


	Vector Vector::operator - (Vector &v)
	{
		Vector temp;

		temp.vector[0]=vector[0]-v.vector[0];
		temp.vector[1]=vector[1]-v.vector[1];
		temp.vector[2]=vector[2]-v.vector[2];

		return temp;
	}

	Vector Vector::operator * (Vector &v)
	{
		Vector temp;

		temp.vector[0]=vector[0]*v.vector[0];
		temp.vector[1]=vector[1]*v.vector[1];
		temp.vector[2]=vector[2]*v.vector[2];

		return temp;
	}

	Vector Vector::operator * (float &f)
	{
		Vector temp;

		temp.vector[0]=vector[0]*f;
		temp.vector[1]=vector[1]*f;
		temp.vector[2]=vector[2]*f;

		return temp;
	}

	Vector Vector::operator / (Vector &v)
	{
		Vector temp;

		for (int i=0;i<3;i++)
		{
			if (v.vector[i]!=0)	
				temp.vector[0]=vector[0]/v.vector[0];
			else 
				logFile.Println("ERROR: Divide by Zero (Vector) in Vector Object");
		}

		return temp;
	}

	Vector Vector::operator / (float &f)
	{
		Vector temp;

		if (f!=0)	
		{
			temp.vector[0]=vector[0]/f;
			temp.vector[1]=vector[1]/f;
			temp.vector[2]=vector[2]/f;
		}

		else 
			logFile.Error("Divide by Zero (float) in Vector Object");

		return temp;
	}

	bool Vector::operator == (Vector &v)
	{
		if(v.vector[0]==vector[0] && v.vector[1]==vector[1] && v.vector[2]==vector[2])
			return true;

		return false;
	}

	bool Vector::operator != (Vector &v)
	{
		if(v.vector[0]!=vector[0] || v.vector[1]!=vector[1] || v.vector[2]!=vector[2])
			return true;

		return false;
	}


	void Vector::setVector(Vector v)
	{
		vector[0]=v.vector[0];
		vector[1]=v.vector[1];
		vector[2]=v.vector[2];
	}

	float* Vector::getArray()
	{
		return vector;
	}

	float Vector::x()
	{
		return vector[0];
	}

	float Vector::y()
	{
		return vector[1];
	}

	float Vector::z()
	{
		return vector[2];
	}

	float Vector::dot(Vector v)
	{
		float temp;

		temp= vector[0]*v.vector[0] + vector[1]*v.vector[1] + vector[2]*v.vector[2];

		return temp;
	}

	Vector Vector::cross(Vector v)
	{
		Vector temp;

		temp.vector[0]= (vector[1]*v.vector[2]) - (vector[2]*v.vector[1]);
		temp.vector[1]= (vector[2]*v.vector[0]) - (vector[0]*v.vector[2]);
		temp.vector[2]= (vector[0]*v.vector[1]) - (vector[1]*v.vector[0]);

		return temp;
	}

	Vector Vector::normalize()
	{
		Vector temp;
		float invLength=length();
		if(invLength==0.0)
			invLength=1.0;
		else
			invLength=1.0f/invLength;

		temp.vector[0]=vector[0]*invLength;
		temp.vector[1]=vector[1]*invLength;
		temp.vector[2]=vector[2]*invLength;

		return temp;
	}

	float Vector::length()
	{
		return (float)sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
	}

	void Vector::Print()
	{
		logFile.Println("Vector: (%f,%f,%f)",vector[0],vector[1],vector[2]);
	}

}